home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / inlin219.zip / UNINLINE.PAS < prev    next >
Pascal/Delphi Source File  |  1987-09-27  |  23KB  |  838 lines

  1. {$R-}    {Range checking off}
  2. {$B-}    {Boolean short circuiting off}
  3. {$S-}    {Stack checking off}
  4. {$I+}    {I/O checking on}
  5. {$N-}    {No numeric coprocessor}
  6. {$V-}    {Relaxed String Checking}
  7. {$M 65500,16384,655360} {Turbo 3 default stack and heap}
  8.  
  9.                           {UNINLINE7}
  10. (*********  Source code Copyright 1986, by L. David Baldwin   *********)
  11. {
  12. Version 1.1.  Convert to Turbo 4.
  13. }
  14. program Inline_disasm;
  15.  
  16. Uses
  17.   Crt;
  18.  
  19. Const
  20.   Tab = 9;
  21.   Signon1 : String[35] = ^M^J'Inline Disassembler, Vers 1.1'^M^J;
  22.   Signon2 : String[40] = '(C) Copyright 1986 by L. David Baldwin'^M^J;
  23.  
  24.   Ulen=80;
  25.   Symbolleng=28;
  26.   MaxByte=Maxint;
  27.   Tokenleng=7;
  28.   MaxLabels=300;
  29.   PhraseOk=True;
  30.   FirstTab=7;
  31.   SecondTab=15;
  32. Type
  33.   Byteptr=^Byte;
  34.   Ptrrec=Record R,S :Word; end;
  35.   String8=String[8];
  36.   String127=String[127];
  37.   String2=Array[1..2] of Char;
  38.   Filestring=String[64];
  39.   Regstrtype=Array[0..15] of Array[1..2] of Char;
  40.   Segregtype=Array[0..3] of Array[1..2] of Char;
  41.  
  42. {Packet holds a displacement which may be either in phrase form (symbolic
  43.   expression) or numeric form.  It may be of byte or word size}
  44.   Packet =Record
  45.            Dispsize :(Bytesize,Wordsize);
  46.            case Phrase : Boolean of  {either a numeric or symbollic phrase}
  47.               True   :(S :String[Symbolleng]);
  48.               False  :(Value : Integer);
  49.            end;
  50.   Line = Record  {Disassembled instruction is built up in a 'line'}
  51.           case Boolean of
  52.             True:  (S:String[Ulen]);
  53.             False :(Len : Byte; PCsave : Integer);
  54.            end;
  55. Var
  56.   Ustring : Line;
  57.   Chi,PC,PCstart,PCfinish : Integer;
  58.   NValue :Word;
  59.   Token : String[Tokenleng];
  60.   Pair : String2;
  61.   LCh : Char Absolute Pair;
  62.   UCh     :Char;
  63.   St      :String127;
  64.   Symname:String[Symbolleng];
  65.   EofInf,BytePending,Firsttime,Wd,ToReg,PrefixFl,Wait_Found : Boolean;
  66.   Reg,Mode,Rm : Word;
  67.   Opcode,PendingByte :Byte;
  68.   UsIndex,TIndex,LabelIndx,ErrCount : Integer;
  69.   TextArray : Array[0..MaxByte] of Char;
  70.   Inf,Outf : Text;
  71.   Labels : Array[0..MaxLabels] of Record          {Holds info on needed labels}
  72.              PCvalue : Integer; Found : Boolean;
  73.              end;
  74.  
  75. Const Opcodes : Array[0..$FF] of Byte = (
  76.    5,5,5,5,5,5,73,71,69,69,69,69,69,69,73,20,
  77.    4,4,4,4,4,4,73,71,86,86,86,86,86,86,73,71,
  78.    6,6,6,6,6,6,24,18,97,97,97,97,97,97,16,19,
  79.    102,102,102,102,102,102,91,0,13,13,13,13,13,13,23,3,
  80.    29,29,29,29,29,29,29,29,21,21,21,21,21,21,21,21,
  81.    73,73,73,73,73,73,73,73,71,71,71,71,71,71,71,71,
  82.    20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
  83.    49,46,34,41,37,43,35,42,51,48,50,47,38,44,39,45,
  84.    20,20,20,20,98,98,100,100,62,62,62,62,62,54,62,71,
  85.    67,100,100,100,100,100,100,100,8,17,7,99,74,72,84,52,
  86.    62,62,62,62,63,64,14,15,98,98,95,96,57,58,87,88,
  87.    62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
  88.    20,20,80,80,55,53,62,62,20,20,81,81,32,30,31,33,
  89.    20,20,20,20,2,1,20,101,20,20,20,20,20,20,20,20,
  90.    61,60,59,36,28,28,70,70,7,40,40,40,28,28,70,70,
  91.    56,20,79,78,25,12,20,20,9,92,11,94,10,93,20,20);
  92.  
  93. Const Grp1_2names : Array[0..15] of Byte =
  94.                (98,75,68,66,65,27,22,26,29,21,7,7,40,40,73,75);
  95.  
  96. Const Shiftnames : Array[0..7] of Byte =(82,83,76,77,89,90,75,85);
  97.  
  98. Const Immednames : Array[0..7] of Byte = (5,69,4,86,6,97,102,13);
  99.  
  100. Const Instrnames : Array[0..102] of String[6] = (
  101. 'AAA',  'AAD',   'AAM',  'AAS',  'ADC',  'ADD',  'AND',  'CALL', 'CBW',  'CLC',
  102. 'CLD',  'CLI',   'CMC',  'CMP',  'CMPSB','CMPSW','CS:',  'CWD',  'DAA',  'DAS',
  103. 'DB',   'DEC',   'DIV',  'DS:',  'ES:',  'HLT',  'IDIV', 'IMUL', 'IN',   'INC',
  104. 'INT',  'INTO',  'INT 3','IRET', 'JB',   'JBE',  'JCXZ', 'JZ',   'JL',   'JLE',
  105. 'JMP',  'JNB',   'JA',   'JNZ',  'JGE',  'JG',   'JNO',  'JPO',  'JNS',  'JO',
  106. 'JPE',  'JS',    'LAHF', 'LDS',  'LEA',  'LES',  'LOCK', 'LODSB','LODSW','LOOP',
  107. 'LOOPE','LOOPNE','MOV',  'MOVSB','MOVSW','MUL',  'NEG',  'NOP',  'NOT',  'OR',
  108. 'OUT',  'POP',   'POPF', 'PUSH', 'PUSHF','???',  'RCL',  'RCR',  'REPE', 'REPNE',
  109. 'RET',  'RETF',  'ROL',  'ROR',  'SAHF' ,'SAR',  'SBB',  'SCASB','SCASW','SHL',
  110. 'SHR',  'SS:',   'STC',  'STD',  'STI',  'STOSB','STOSW','SUB',  'TEST', 'WAIT',
  111. 'XCHG', 'XLAT',  'XOR');
  112.  
  113.  
  114. Const   RegStr : Regstrtype = (
  115.                 'AX','CX','DX','BX','SP','BP','SI','DI',
  116.                 'AL','CL','DL','BL','AH','CH','DH','BH');
  117.         SegRegStr : Segregtype = ('ES','CS','SS','DS');
  118.  
  119.  
  120. {-------------OutUstring}
  121. PROCEDURE OutUstring;
  122. Var Tmp : Integer;
  123. begin
  124. (* WriteLn(Ustring.S);      *)
  125. if TIndex < MaxByte-Ulen then
  126.   begin
  127.   Tmp:=Ustring.Len+1;
  128.   Move(Ustring, TextArray[TIndex], Tmp);
  129.   TIndex:=TIndex+Tmp;
  130.   end
  131. else
  132.   begin
  133.   WriteLn('Output Array Overflow');
  134.   Halt(1);
  135.   end;
  136. end;
  137.  
  138. {-------------Error}
  139. PROCEDURE Error(II :Integer; S :String127);
  140. Var X,Y : Integer;
  141.   NewS : String127;
  142. begin
  143. GotoXY(1,WhereY);
  144. WriteLn(St);
  145. Y:=WhereY;
  146. X:=II-3; if X<1 then X:=1;
  147. GotoXY(X, Y);
  148. Write('^');
  149. if S[0]>#0 then  NewS:='Error, '+S else NewS:='Error';
  150. if X+Ord(NewS[0])>80 then X:=X-Ord(NewS[0]) else X:=X+1;
  151. GotoXY(X,Y);  WriteLn(NewS);
  152. ErrCount:=Succ(ErrCount);
  153. if ErrCount>6 then
  154.   begin
  155.   WriteLn('Excessive Number of Errors');
  156.   Halt(1);
  157.   end;
  158. end;
  159.  
  160.  
  161. PROCEDURE ByteErr; Forward;
  162. PROCEDURE NumbyteErr; Forward;
  163. {$I unpars.inc}
  164.  
  165. {-------------InsrtChr}
  166. PROCEDURE InsrtChr(C :Char);
  167. begin
  168. Ustring.S[UsIndex]:=C;
  169. if Ustring.Len<UsIndex then Ustring.Len:=UsIndex;
  170. UsIndex:=UsIndex+1;
  171. end;
  172.  
  173. {-------------Comma}
  174. PROCEDURE Comma;
  175. begin  InsrtChr(','); end;
  176.  
  177. {-------------InsrtSt}
  178. PROCEDURE InsrtSt(S :String127);
  179. Var     K       :Integer;
  180. begin
  181. for K:=1 to Ord(S[0]) do
  182.    begin
  183.    InsrtChr(S[K]);
  184.    end;
  185. end;
  186.  
  187. Type String4=String[4];
  188. {-------------Hex2}
  189. FUNCTION Hex2(B :Byte): String4;
  190. Const HexDigs :Array[0..15] of Char = '0123456789ABCDEF';
  191. Var Bz :Byte;
  192. begin
  193. Bz:=B and $F;  B:=B Shr 4;
  194. Hex2:=HexDigs[B]+HexDigs[Bz];
  195. end;
  196.  
  197. {-------------Hex4}
  198. FUNCTION Hex4(W :Integer): String4;
  199. begin Hex4:=Hex2(Hi(W))+Hex2(Lo(W)); end;
  200.  
  201. {-------------Insrthx2}
  202. PROCEDURE Insrthx2(B :Byte);
  203. begin
  204. InsrtChr('$');
  205. InsrtSt(Hex2(B));
  206. end;
  207.  
  208. {-------------Insrthx4}
  209. PROCEDURE Insrthx4(W :Word);
  210. begin
  211. InsrtChr('$');
  212. InsrtSt(Hex4(W));
  213. end;
  214.  
  215. {-------------InsrtDisp}
  216. PROCEDURE InsrtDisp(Disp : Packet);
  217. begin
  218. with Disp do
  219.   if not Phrase then
  220.     begin
  221.     if (Dispsize=Bytesize)  then
  222.        begin
  223.        if Value and $80 <>0 then
  224.           begin
  225.           InsrtChr('-');  {turn into negative number}
  226.           Value:=-(Value or $FF00);
  227.           end
  228.        else InsrtChr('+');
  229.        Insrthx2(Lo(Value));
  230.        end
  231.     else
  232.        Insrthx4(Value);
  233.     end
  234.   else InsrtSt(S);
  235. end;
  236.  
  237. {-------------FormLabel}
  238. FUNCTION FormLabel(N : Integer): String8;
  239. Var S : String8;
  240. begin
  241. Str(N,S);
  242. FormLabel:='X'+S;
  243. end;
  244.  
  245. {-------------OutLabel}
  246. PROCEDURE OutLabel(N : Integer);
  247.  
  248.   PROCEDURE AddLabel(N : Integer);
  249.   Var I : Integer; Fnd : Boolean;
  250.   begin
  251.   Fnd:=False;   {only add label if it isn't already there}
  252.   I:=0;
  253.   while (I<LabelIndx) and not Fnd do
  254.     begin Fnd:=Labels[I].PCvalue=N;  I:=Succ(I); end;
  255.   if not Fnd then
  256.     if LabelIndx<=MaxLabels then
  257.       with Labels[LabelIndx] do
  258.         begin
  259.         PCvalue:=N;
  260.         Found:=False;   {will try to find it later}
  261.         LabelIndx:=Succ(LabelIndx);
  262.         end;
  263.   end;
  264. begin
  265. AddLabel(N);
  266. InsrtSt(FormLabel(N));
  267. end;
  268.  
  269. {-------------ByteErr}
  270. PROCEDURE ByteErr;
  271. begin
  272. Error(Chi,'Byte Exp');
  273. Next;  {pass it by}
  274. PC:=Succ(PC);
  275. end;
  276.  
  277. {-------------NumbyteErr}
  278. PROCEDURE NumbyteErr;
  279. begin
  280. Error(Chi,'Numerical Byte Exp');
  281. Next;  {pass it by}
  282. PC:=Succ(PC);
  283. end;
  284.  
  285. {-------------ShortJump}
  286. PROCEDURE ShortJump;
  287. {the short jump instructions}
  288. Var Pk : Packet;
  289.     Vl : Word;
  290. begin
  291. if not GetByte(Pk,PhraseOk) then ByteErr;
  292. if (Opcode=$EB) then InsrtSt('SHORT ');
  293. with Pk do
  294.   if not Phrase then
  295.     begin
  296.     Vl:=Value;
  297.     if (Vl and $80 <>0) then Vl:=Vl or $FF00;  {sign extend}
  298.     Vl:=Vl+PC;
  299.     OutLabel(Vl);
  300.     end
  301.   else InsrtDisp(Pk);
  302. end;
  303.  
  304. {-------------IntraSeg}